/*
 * author      : 吴中勤 
 * date        : 2019/3/30
 * description : TODO
 */

package org.wzq.learn.infrastructure.framework.config;

import brave.Tracing;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.sleuth.SpanNamer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.wzq.learn.infrastructure.lib.trace.ErrorReporter;
import org.wzq.learn.infrastructure.lib.trace.FeignClientInterceptor;
import org.wzq.learn.infrastructure.lib.trace.FilterInitContext;
import org.wzq.learn.infrastructure.lib.trace.threadpool.CustomThreadPool;

import javax.annotation.PostConstruct;

@Configuration
public class ThreadRelativeConfig {

    // https://stackoverflow.com/questions/32201870/handle-userredirectrequiredexception-a-redirect-is-required-to-get-the-users-ap/32227901
    // 解决 线程中 OAuth2 redirect 问题, 把上下文变成 inheritable threadlocal
//    @Bean
//    public MethodInvokingFactoryBean methodInvokingFactoryBean() {
//        MethodInvokingFactoryBean methodInvokingFactoryBean = new MethodInvokingFactoryBean();
//        methodInvokingFactoryBean.setTargetClass(SecurityContextHolder.class);
//        methodInvokingFactoryBean.setTargetMethod("setStrategyName");
//        methodInvokingFactoryBean.setArguments(new String[]{SecurityContextHolder.MODE_INHERITABLETHREADLOCAL});
//        return methodInvokingFactoryBean;
//    }

    @Autowired
    private Tracing tracing;

    @Autowired
    private SpanNamer spanNamer;

    /* 初始化自定义线程池,  */
    @Bean
    public CustomThreadPool customeThreadPool() {
        // return new CustomThreadPool(tracing, spanNamer);

        // 以下仅作测试
        return new CustomThreadPool(tracing, spanNamer, 1, 1, 1);
    }

    // 自定义的feign拦截, 设置相关请求头
    @Bean
    public FeignClientInterceptor feignClientInterceptor() {
        return new FeignClientInterceptor();
    }

    // 自定义filter, 读取相关请求头
    @Bean
    public FilterInitContext myZipkinFilter() {
        return new FilterInitContext(tracing.tracer());
    }

    @Value("${spring.application.name}")
    String serviceName;

    @Value("${sentry.dsn}")
    String sentryDsn;

    @PostConstruct
    public void initStaticContext() {
        /* 初始化 ErrorReporter */
        ErrorReporter.init(serviceName, sentryDsn);
    }
}
